<script setup lang="ts">
import { computed } from 'vue';
import type { VNode } from 'vue';
import { $t } from '@/locales';
import { useTabStore } from '@/store/modules/tab';
import { useSvgIcon } from '@/hooks/common/icon';

defineOptions({
    name: 'ContextMenu'
});

interface Props {
    /** ClientX */
    x: number;
    /** ClientY */
    y: number;
    tabId: string;
    excludeKeys?: App.Global.DropdownKey[];
    disabledKeys?: App.Global.DropdownKey[];
}

const props = withDefaults(defineProps<Props>(), {
    excludeKeys: () => [],
    disabledKeys: () => []
});

const visible = defineModel<boolean>('visible');

const { removeTab, clearTabs, clearLeftTabs, clearRightTabs } = useTabStore();
const { SvgIconVNode } = useSvgIcon();

type DropdownOption = {
    key: App.Global.DropdownKey;
    label: string;
    icon?: () => VNode;
    disabled?: boolean;
};

const options = computed(() => {
    const opts: DropdownOption[] = [
        {
            key: 'closeCurrent',
            label: $t('dropdown.closeCurrent'),
            icon: SvgIconVNode({ icon: 'ant-design:close-outlined', fontSize: 18 })
        },
        {
            key: 'closeOther',
            label: $t('dropdown.closeOther'),
            icon: SvgIconVNode({ icon: 'ant-design:column-width-outlined', fontSize: 18 })
        },
        {
            key: 'closeLeft',
            label: $t('dropdown.closeLeft'),
            icon: SvgIconVNode({ icon: 'mdi:format-horizontal-align-left', fontSize: 18 })
        },
        {
            key: 'closeRight',
            label: $t('dropdown.closeRight'),
            icon: SvgIconVNode({ icon: 'mdi:format-horizontal-align-right', fontSize: 18 })
        },
        {
            key: 'closeAll',
            label: $t('dropdown.closeAll'),
            icon: SvgIconVNode({ icon: 'ant-design:line-outlined', fontSize: 18 })
        }
    ];
    const { excludeKeys, disabledKeys } = props;

    const result = opts.filter((opt) => !excludeKeys.includes(opt.key));

    disabledKeys.forEach((key) => {
        const opt = result.find((item) => item.key === key);

        if (opt) {
            opt.disabled = true;
        }
    });

    return result;
});

function hideDropdown() {
    visible.value = false;
}

const dropdownAction: Record<App.Global.DropdownKey, () => void> = {
    closeCurrent() {
        removeTab(props.tabId);
    },
    closeOther() {
        clearTabs([props.tabId]);
    },
    closeLeft() {
        clearLeftTabs(props.tabId);
    },
    closeRight() {
        clearRightTabs(props.tabId);
    },
    closeAll() {
        clearTabs();
    }
};

function handleDropdown(optionKey: App.Global.DropdownKey) {
    dropdownAction[optionKey]?.();
    hideDropdown();
}
</script>

<template>
    <NDropdown
        :show="visible"
        placement="bottom-start"
        trigger="manual"
        :x="x"
        :y="y"
        :options="options"
        @clickoutside="hideDropdown"
        @select="handleDropdown"
    />
</template>

<style scoped></style>
